from django.db import models
from tushare_data.models import StockBasic, ThsPlate
from .constant import DATA_ANALYSIS_TYPES


class StockPerformanceDaily(models.Model):
    """股票表现统计数据"""
    ts_code = models.CharField(max_length=10, primary_key=True, verbose_name='TS代码')
    name = models.CharField(max_length=20, verbose_name='股票名称')
    date = models.DateField()

    # 价格统计
    price = models.FloatField(null=True, blank=True, help_text='收盘价格')
    price_range = models.FloatField(null=True, blank=True, help_text='价格振幅')
    price_real_body = models.FloatField(null=True, blank=True, help_text='实体部分')
    # 技术指标.均线是主力资金重要的分析对手盘成本的指标，尤其是60日均线，因为主力通常吸筹的周期为3个月左右。
    # 另外，短期均线一般比较敏感，但是不能作为趋势判断指标。所以这里也只选用5日均线、10日均线、20日均线、60日均线作为判断指标。
    ma5 = models.FloatField(null=True, blank=True, help_text='5日均线')
    ma10 = models.FloatField(null=True, blank=True, help_text='10日均线')
    ma20 = models.FloatField(null=True, blank=True, help_text='20日均线')
    #最多看到60即可。这是买入的必要条件，必须要站上60日均线，并且60日均线要拐头向上。
    # 这个指标，对于主力资金的买卖点非常有用，因为主力资金操作量很大，单日行情经常会有大幅的波动，但对于中线主力资金来说，通常需要60日均线向上，表示是持仓区间。
    # 考虑到中线资金占比很大，短、中期也必须满足条件，因为中线资金的波动对整个价格的影响很大。因此，这里只统计60日均线。
    ma60 = models.FloatField(null=True, blank=True, help_text='60日均线')
    # 成交量统计
    amount = models.FloatField(null=True, blank=True, help_text='平均成交量')
    amount_ma5 = models.FloatField(null=True, blank=True, help_text='5日平均成交量')
    # 换手率统计，这是主力资金成交的绝对量，也可以反映市场交易热度，绝对数值越高，交易越活跃，但主力占比不一定很大。
    # 相对指标，如换手率与上一交易日相比增加3%以上，则可能是主力流入，相对降低说明主力流出。根据换手率和主力资金流入流出判断资金动向。
    turnover_rate = models.FloatField(null=True, blank=True, help_text='换手率')
    turnover_chg_pct = models.FloatField(null=True, blank=True, help_text='换手率相对上交易日变化百分比')

    class Meta:
        db_table = 'data_analysis_stock_daily'
        unique_together = ('ts_code', 'date')
        indexes = [
            models.Index(fields=['ts_code', 'date']),
            models.Index(fields=['date']),
        ]
    
    def __str__(self):
        return f"{self.ts_code} - {self.date}"


class SectorPerformanceDaily(models.Model):
    """板块表现统计数据"""
    ts_code = models.CharField(max_length=20, primary_key=True, verbose_name='板块代码')
    name = models.CharField(max_length=100, verbose_name='板块名称')
    date = models.DateField(verbose_name='日期')
    price = models.FloatField(null=True, blank=True, help_text='收盘价格')
    amount = models.FloatField(null=True, blank=True, help_text='成交量')
    price_chg_pct = models.FloatField(null=True, blank=True, help_text='涨跌幅')
    amount_chg_pct = models.FloatField(null=True, blank=True, help_text='成交量环比')
    # 成分股统计
    stock_count = models.IntegerField(null=True, blank=True, help_text='成分股数量')
    up_count = models.IntegerField(null=True, blank=True, help_text='上涨股票数量')
    down_count = models.IntegerField(null=True, blank=True, help_text='下跌股票数量')
    zt_count = models.IntegerField(null=True, blank=True, help_text='涨停股票数量')
    
    # 领涨领跌,只关注两个
    top_stock_code = models.CharField(max_length=20, null=True, blank=True, help_text='领涨股票代码')
    top_stock_name = models.CharField(max_length=100, null=True, blank=True, help_text='领涨股票名称')
    top_stock_pct = models.FloatField(null=True, blank=True, help_text='领涨股票涨幅')
    second_stock_code = models.CharField(max_length=20, null=True, blank=True, help_text='次领涨股票代码')
    second_stock_name = models.CharField(max_length=100, null=True, blank=True, help_text='次领涨股票名称')
    second_stock_pct = models.FloatField(null=True, blank=True, help_text='次领涨股票涨幅')
    
    #连续3日涨幅
    up_chg_pct_3 = models.FloatField(null=True, blank=True, help_text='3日涨幅')#用于判断板块持续性
    up_chg_pct_5 = models.FloatField(null=True, blank=True, help_text='5日涨幅')#用于判断出场的时机
    #板块涨幅指标，一般看板块是否已经见顶，如果板块整体上涨，但是单个股票涨跌幅度差别很大，说明板块开始见顶回落，可以减持，甚至清仓离场。
    up_chg_pct_10 = models.FloatField(null=True, blank=True, help_text='10日涨幅')
    up_chg_pct_20 = models.FloatField(null=True, blank=True, help_text='20日涨幅')#用于判断入场的时机
    class Meta:
        unique_together = ('ts_code', 'date')
        db_table = 'data_analysis_sector_daily'
        indexes = [
            models.Index(fields=['ts_code', 'date']),
            models.Index(fields=['date']),
        ]
    
    def __str__(self):
        return f"{self.name} - {self.date}"


class MarketSummary(models.Model):
    """市场整体统计数据"""
    date = models.DateField(unique=True)
    
    # 大盘指数
    sh_index = models.FloatField(null=True, blank=True, help_text='上证指数')
    sh_change_pct = models.FloatField(null=True, blank=True, help_text='上证指数变化百分比')
    
    sz_index = models.FloatField(null=True, blank=True, help_text='深证成指')
    sz_change_pct = models.FloatField(null=True, blank=True, help_text='深证成指变化百分比')
    
    cyb_index = models.FloatField(null=True, blank=True, help_text='创业板指')
    cyb_change_pct = models.FloatField(null=True, blank=True, help_text='创业板指变化百分比')
    
    # 市场统计
    total_stocks = models.IntegerField(null=True, blank=True, help_text='总股票数')

    up_stocks = models.IntegerField(default=0,null=True, blank=True, help_text='上涨股票数')
    down_stocks = models.IntegerField(default=0,null=True, blank=True, help_text='下跌股票数')
    # 涨跌停统计,采用tushare的涨跌停个股数据（不含ST）
    limit_up_stocks = models.IntegerField(null=True, blank=True, help_text='涨停股票数')
    limit_down_stocks = models.IntegerField(null=True, blank=True, help_text='跌停股票数')
    
    # 详细涨跌区间统计,不考虑新股，单独统计
    up_7_pct = models.IntegerField(null=True, blank=True, help_text='上涨大于7%股票数')
    up_5_to_up_7_pct = models.IntegerField(null=True, blank=True, help_text='5%-7%区间股票数')
    up_2_to_5_pct = models.IntegerField(null=True, blank=True, help_text='上涨2%-5%区间股票数')
    up_0_to_2_pct = models.IntegerField(null=True, blank=True, help_text='上涨0%-2%区间股票数')
    flat_stocks = models.IntegerField(null=True, blank=True, help_text='平盘股票数')
    down_0_to_2_pct = models.IntegerField(null=True, blank=True, help_text='下跌0%-2%区间股票数')
    down_2_to_5_pct = models.IntegerField(null=True, blank=True, help_text='下跌2%-5%区间股票数')
    down_5_to_7_pct = models.IntegerField(null=True, blank=True,help_text='下跌5%-7%区间股票数')
    down_7_pct = models.IntegerField(null=True, blank=True, help_text='下跌7%以上股票数')
    
    # 两市成交统计（只计算上证和深证）
    total_amount = models.FloatField(null=True, blank=True, help_text='总成交额（亿元）')
    
    class Meta:
        indexes = [
            models.Index(fields=['date']),
        ]
    
    def __str__(self):
        return f"Market Summary - {self.date}"

class AmountEnergy(models.Model):
    """
    量能统计模型
    """
    date = models.DateField(verbose_name='日期', primary_key=True)
    hs_amount = models.FloatField(verbose_name='沪深量能')
    sh_amount = models.FloatField(verbose_name='上证量能')
    sz_amount = models.FloatField(verbose_name='深证量能')
    cyb_amount = models.FloatField(verbose_name='创业板量能')

    class Meta:
        db_table = 'data_analysis_energy'
        verbose_name = '量能统计'
        verbose_name_plural = verbose_name

    def __str__(self):
        return f'{self.date}量能统计'

class DataAnalysisRecord(models.Model):
    """
    数据分析记录模型，用于跟踪各类分析数据的更新状态
    """
    data_name = models.CharField(max_length=100, verbose_name='数据分析名称')
    data_type = models.CharField(max_length=20, choices=DATA_ANALYSIS_TYPES, verbose_name='分析类型')
    last_trade_date = models.DateField(verbose_name='最新交易日期')
    analysis_date = models.DateField(auto_now=True, verbose_name='分析日期')
    
    class Meta:
        verbose_name = '数据分析记录'
        verbose_name_plural = '数据分析记录'
        db_table = 'data_analysis_update_record'
        unique_together = ('data_name', 'data_type')
    
    def __str__(self):
        return f"{self.data_name} ({self.get_data_type_display()}) - 最新交易日期: {self.last_trade_date}"
    
    @classmethod
    def get_last_trade_date(cls, data_name, data_type='day'):
        """
        获取指定数据分析类型的最新交易日期
        
        Args:
            data_name (str): 数据分析名称
            data_type (str): 分析类型，默认为'day'
            
        Returns:
            date: 最新交易日期，如果没有记录则返回None
        """
        try:
            record = cls.objects.get(data_name=data_name, data_type=data_type)
            return record.last_trade_date
        except cls.DoesNotExist:
            return None
    
    @classmethod
    def update_record(cls, data_name, data_type, last_trade_date):
        """
        更新或创建数据分析记录
        
        Args:
            data_name (str): 数据分析名称
            data_type (str): 分析类型
            last_trade_date (date): 最新交易日期
            
        Returns:
            DataAnalysisRecord: 更新或创建的记录对象
        """
        record, created = cls.objects.update_or_create(
            data_name=data_name,
            data_type=data_type,
            defaults={'last_trade_date': last_trade_date}
        )
        return record

